package com.crazyteam.datasource.factory;

import org.springframework.beans.factory.config.YamlProcessor;
import org.springframework.core.env.MapPropertySource;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.EncodedResource;
import org.springframework.core.io.support.PropertySourceFactory;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Properties;

/**
 * @author guoyang
 * @Date 2018-01-09
 * @Desc YML 解析工厂 配合 PropertySource可注入yml 文件配置
 * demo: @PropertySource(value="datasourceConf.yml", factory = YmlSourceFactory.class)
 * @see org.springframework.context.annotation.PropertySource
 */
public class YmlSourceFactory implements PropertySourceFactory {

    @Override
    public PropertySource<?> createPropertySource(String name, EncodedResource resource) throws IOException {
        if (StringUtils.isEmpty(name)){
            name = resource.getResource().getFilename();
        }
        if (ClassUtils.isPresent("org.yaml.snakeyaml.Yaml", null)) {
            Processor processor = new Processor(resource.getResource());
            Map<String, Object> source = processor.process();
            if (!source.isEmpty()) {
                return new MapPropertySource(name, source);
            }
        }
        return null;
    }

    private static class Processor extends YamlProcessor {

        Processor(Resource resource) {
            setResources(resource);
        }

        public Map<String, Object> process() {
            final Map<String, Object> result = new LinkedHashMap<String, Object>();
            process(new MatchCallback() {
                @Override
                public void process(Properties properties, Map<String, Object> map) {
                    result.putAll(getFlattenedMap(map));
                }
            });
            return result;
        }

    }
}
